package com.tsfyun.scm.service.impl.risk;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.ImmutableMap;
import com.tsfyun.common.base.dto.TaskDTO;
import com.tsfyun.common.base.enums.domain.*;
import com.tsfyun.common.base.enums.risk.RiskApprovalDocTypeEnum;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.security.SecurityUtil;
import com.tsfyun.common.base.support.DomainStatus;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.scm.dto.risk.RiskApprovalQTO;
import com.tsfyun.scm.dto.support.TaskNoticeContentDTO;
import com.tsfyun.scm.entity.risk.RiskApproval;
import com.tsfyun.scm.mapper.risk.RiskApprovalMapper;
import com.tsfyun.scm.service.common.ICommonService;
import com.tsfyun.scm.service.finance.IPaymentAccountService;
import com.tsfyun.scm.service.order.IImpOrderService;
import com.tsfyun.scm.service.risk.IRiskApprovalService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.service.support.ITaskNoticeContentService;
import com.tsfyun.scm.service.system.IStatusHistoryService;
import com.tsfyun.scm.vo.risk.RiskApprovalVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 风控审批 服务实现类
 * </p>
 *

 * @since 2020-05-08
 */
@RefreshScope
@Slf4j
@Service
public class RiskApprovalServiceImpl extends ServiceImpl<RiskApproval> implements IRiskApprovalService {

    @Autowired
    private RiskApprovalMapper riskApprovalMapper;
    @Autowired
    private IStatusHistoryService statusHistoryService;
    @Value("${redis.lock.time:5}")
    private Integer lockTime;
    @Autowired
    private ITaskNoticeContentService taskNoticeContentService;
    @Autowired
    private ICommonService commonService;
    @Autowired
    private IImpOrderService impOrderService;
    @Autowired
    private IPaymentAccountService paymentAccountService;

    @Override
    public PageInfo<RiskApprovalVO> pageList(RiskApprovalQTO qto) {
        Map<String,Object> params = beanMapper.map(qto, Map.class);
        PageHelper.startPage(qto.getPage(),qto.getLimit());
        List<RiskApprovalVO> list = riskApprovalMapper.list(params);
        return new PageInfo<>(list);
    }

    @Override
    public RiskApprovalVO detail(Long id,String operation) {
        RiskApprovalVO riskApproval = riskApprovalMapper.detail(id);
        Optional.ofNullable(riskApproval).orElseThrow(()->new ServiceException("风控审批单据不存在"));
        DomainStatus.getInstance().check(DomainOprationEnum.of(operation), riskApproval.getStatusId());
        return riskApproval;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitRiskApproval(RiskApproval ra) {
        RiskApprovalStatusEnum statusEnum = RiskApprovalStatusEnum.WAIT_EXAMINE;
        ra.setStatusId(statusEnum.getCode());
        //保存风控审批单据
        super.saveNonNull(ra);
        DomainOprationEnum oprationEnum = DomainOprationEnum.RISK_APPROVAL_AUDIT;
        //记录历史状态
        statusHistoryService.saveHistory(oprationEnum,
                ra.getId().toString(),RiskApproval.class.getName(),
                statusEnum.getCode(),statusEnum.getName(),ra.getApprovalReason()
        );
        //任务通知
        TaskNoticeContentDTO taskNoticeContentDTO = new TaskNoticeContentDTO();
        taskNoticeContentDTO.setDocumentType(DomainTypeEnum.RISKAPPROVAL.getCode());
        taskNoticeContentDTO.setDocumentId(ra.getId().toString());
        taskNoticeContentDTO.setCustomerId(ra.getCustomerId());
        taskNoticeContentDTO.setOperationCode(oprationEnum.getCode());
        taskNoticeContentDTO.setContent(String.format("【%s】需要您审批，审核类型【%s】审批原因：%s，%s", ra.getDocNo(),RiskApprovalDocTypeEnum.of(ra.getDocType()).getName(),ra.getSubmitter(),StringUtils.removeSpecialSymbol(ra.getApprovalReason())));
        taskNoticeContentDTO.setQueryParamsMap(ImmutableMap.of("docNo",ra.getDocNo()));
        taskNoticeContentService.add(taskNoticeContentDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void approval(TaskDTO dto) {
        RiskApproval riskApproval = commonService.changeDocumentStatus(dto);
        RiskApprovalStatusEnum nowStatusEnum = RiskApprovalStatusEnum.of(dto.getNewStatusCode());
        RiskApprovalDocTypeEnum riskApprovalDocTypeEnum = RiskApprovalDocTypeEnum.of(riskApproval.getDocType());
        switch (riskApprovalDocTypeEnum) {
            case IMP_ORDER_AMOUNT_INSUFFICIENT_MOMEY://进口订单金额异常
                impOrderService.completeRisk(Long.parseLong(riskApproval.getDocId()),Objects.equals(RiskApprovalStatusEnum.APPROVED,nowStatusEnum),dto.getMemo());
                break;
            case PAYMENT_ACCOUNT_RATE_ADJUST://付汇单汇率调整
                paymentAccountService.completeAdjustRateRisk(Long.parseLong(riskApproval.getDocId()),Objects.equals(RiskApprovalStatusEnum.APPROVED,nowStatusEnum),dto.getMemo());
                break;
            case PAYMENT_ACCOUNT_INSUFFICIENT_MOMEY://付汇单金额异常
                paymentAccountService.completeCostRisk(Long.parseLong(riskApproval.getDocId()),Objects.equals(RiskApprovalStatusEnum.APPROVED,nowStatusEnum),dto.getMemo());
                break;
            default:
                throw new ServiceException("审核类型错误");
        }
        riskApproval.setApprovalInfo(dto.getMemo());
        riskApproval.setApprover(SecurityUtil.getCurrentPersonName());
        super.updateById(riskApproval);
    }

    @Override
    public RiskApproval lastApproval(String docType, String docId) {
        return riskApprovalMapper.lastApproval(docType, docId);
    }

    @Override
    public void removeByDoc(String docType, String docId) {
        RiskApproval riskApproval = lastApproval(docType,docId);
        if(Objects.nonNull(riskApproval)){
            super.removeById(riskApproval.getId());
            clearTaskNotice(riskApproval.getId());
        }
    }

    //清空付款单任务通知
    public void clearTaskNotice(Long id){
        taskNoticeContentService.deleteTaskNotice(DomainTypeEnum.PAYMENTACCOUNT.getCode(), id, "");
    }
}
